package com.smartfactory.sail.service.impl;

import com.ada.base.security.entity.SysUser;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartfactory.sail.dto.OrderItemsDto;
import com.smartfactory.sail.dto.OrderNumDto;
import com.smartfactory.sail.dto.PersonRankingDto;
import com.smartfactory.sail.dto.ShowOrderNumDto;
import com.smartfactory.sail.entity.*;
import com.smartfactory.sail.entity.enums.*;
import com.smartfactory.sail.mapper.OrderItemMapper;
import com.smartfactory.sail.mapper.OrderMapper;
import com.smartfactory.sail.mapper.StorageCurrentInfoMapper;
import com.smartfactory.sail.service.*;
import com.smartfactory.sail.utils.CodeUtils;
import com.smartfactory.sail.utils.DateUtils;
import com.smartfactory.sail.utils.PageUtils;
import com.smartfactory.sail.vo.PageParam;
import com.smartfactory.sail.vo.order.AddContractOrderReq;
import com.smartfactory.sail.vo.order.ListHTOrderListResp;
import com.smartfactory.sail.vo.order.ListOrderItemInfoResp;
import com.smartfactory.sail.vo.order.ListYPOrderListResp;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author 王巨壁
 * @since 2019-07-24
 */

@Transactional
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private IOrderItemService iOrderItemService;
    private OrderMapper orderMapper;
    private OrderItemMapper orderItemMapper;
    private ICustService iCustService;
    private IContractService iContractService;
    private IItemService itemService;
    private StorageCurrentInfoMapper storageCurrentInfoMapper;
    private IItemWorkingprocedureService iItemWorkingprocedureService;

    public OrderServiceImpl(IOrderItemService iOrderItemService, OrderMapper orderMapper, OrderItemMapper orderItemMapper, ICustService iCustService, IContractService iContractService, IItemService itemService, StorageCurrentInfoMapper storageCurrentInfoMapper, IItemWorkingprocedureService iItemWorkingprocedureService) {
        this.iOrderItemService = iOrderItemService;
        this.orderMapper = orderMapper;
        this.orderItemMapper = orderItemMapper;
        this.iCustService = iCustService;
        this.iContractService = iContractService;
        this.itemService = itemService;
        this.storageCurrentInfoMapper = storageCurrentInfoMapper;
        this.iItemWorkingprocedureService = iItemWorkingprocedureService;
    }

    /**
     * 下合同订单
     *
     * @param req
     * @return
     */
    @Transactional
    @Override
    public Long add(AddContractOrderReq req) {

        Cust cust = iCustService.queryCustByName(req.getCustName());
        if (cust == null) {
             cust = new Cust();
            cust.setEnterpriseName(req.getCustName());
            cust.setAddr(req.getCustAddr());
            cust.setId(iCustService.saveCustByOrderInfo(cust, req.getContactsName(), req.getContactInformation()));
        }
        //合同相关
        Contract contract = new Contract();
        contract.setContractCode(req.getContractCode());
        contract.setCustId(cust.getId());
        contract.setCustName(cust.getEnterpriseName());//企业名称
        contract.setCompanyAddress(cust.getAddr());//公司地址
        contract.setContractType(req.getContractType());//合同类型
        contract.setDeliveryDate(req.getDeliveryDate());//交货日期
        contract.setContractImgs(req.getContractImgs());//合同照片
        contract.setContactInformation(req.getContactInformation());//联系方式
        contract.setSignerId(req.getUnderOrderId());//下单人
        contract.setOrderType(req.getOrderMode());//修磨 xxx 什么订单
        contract.setCompanyAddress(cust.getAddr());
        Double contractPrice = 0.0;//合同总价
        //合同金额是多个产品算出来的
        for (OrderItemsDto orderItemsDto : req.getOrderItemsDtos()) {
            contractPrice += orderItemsDto.getOffer() * orderItemsDto.getSize();
        }
        contract.setContractAmount(contractPrice);//合同总价
        contract.setContractType(req.getContractType());//合同类型
        contract.setStatus(ContractStatusEnum.DSC);//状态
        contract.setInvoiceStatus(ContractInvoiceStatusEnum.YKP);
        //保存合同
        boolean save = iContractService.save(contract);
        if (!save) {
            return -1L;
        }

        //订单相关
        Order order = new Order();
        //所有状态从1开始  数字代表状态  参考constants表
        order.setStatus(OrderStatusEnum.CSH);//状态
        order.setOrderCode(CodeUtils.creatOrderCode());//code
        order.setOrderType(OrderItemTypeEnum.HTDD);
        order.setOrderMode(req.getOrderMode());//修磨订单等等
        order.setContractId(contract.getId());//合同id
        order.setCustId(cust.getId());//客户id
        order.setStatus(OrderStatusEnum.CSH);//初始化
        order.setUnderOrderId(req.getUnderOrderId());//下单人
        order.setDeliveryDate(req.getDeliveryDate());//发货时间
        order.setContactsName(req.getContactsName());//联系人名称
        order.setContactInformation(req.getContactInformation());//联系方式
        order.setCustAddr(req.getCustAddr());

        if (this.save(order)) {//保存订单
            Long id = order.getId();
            List<OrderItemsDto> orderItemsDtos = req.getOrderItemsDtos();
            ArrayList<OrderItem> orderItems = new ArrayList<>();
            for (OrderItemsDto orderItemsDto : orderItemsDtos) {
                Item item = itemService.getById(orderItemsDto.getItemId());
                OrderItem orderItem = new OrderItem();
                orderItem.setOrderId(id);
                orderItem.setOrderCode(order.getOrderCode());
                orderItem.setItemId(orderItemsDto.getItemId());
                orderItem.setContractId(contract.getId());
                orderItem.setStatus(OrderItemStatusEnum.DPB);
                orderItem.setItemName(item.getName());
                orderItem.setSize(orderItemsDto.getSize());
                orderItem.setSpecification(item.getSpecification());//
                orderItem.setCustDrawings(orderItemsDto.getCustDrawings()); //客户图纸  必传
                orderItem.setProductDrawings(item.getProductDrawings());//这个要传
                orderItem.setTechnicalDrawings(item.getTechnicalDrawings());//技术图纸
                //   orderItem.setCostPrice(orderItemsDto.getCostPrice());//成本单价
                orderItem.setOffer(orderItemsDto.getOffer());//含税单价
                orderItem.setOrderMode(req.getOrderMode());//修磨订单等等
                orderItem.setUnderOrderId(req.getUnderOrderId());
                orderItem.setDeliveryDate(req.getDeliveryDate());
                orderItem.setCustId(cust.getId());
                orderItem.setCustName(cust.getEnterpriseName());//企业名称
                orderItem.setCustAddr(req.getCustAddr());
                orderItem.setContactsName(req.getContactsName());
                orderItem.setContactInformation(req.getContactInformation());//联系方式
                orderItem.setContractType(contract.getContractType());
                orderItem.setOrderType(order.getOrderType());
                orderItems.add(orderItem);
            }
            if (iOrderItemService.saveBatch(orderItems)) {
                //修改最近合作时间
                @NotBlank Long custId = cust.getId();
                iCustService.updateCooperationTime(custId, DateUtils.getNowDate());

                //初始化 领料项目
              //  iPickingService.saveByOrderItem(orderItems);
                //异步调用
              //  iPurchaseService.orderPurChaseHandle(order.getId());

                return order.getId();
            }
        }
        return -1L;
    }


    @Override
    public IPage<ListHTOrderListResp> getHTorderListPage(PageParam pageParam, Map<String, Object> queryParam) {
        //分页信息
        Page<ListHTOrderListResp> page = new Page<>();
        PageUtils.createPage(page, pageParam);
        QueryWrapper<ListHTOrderListResp> query = new QueryWrapper<>();
        query.allEq(queryParam);
        IPage<ListHTOrderListResp> hTorderListPage = orderMapper.getHTorderListPage(page, query);
        hTorderListPage.getRecords().forEach(listHTOrderListResp -> {
            int i = (int) iItemWorkingprocedureService.orderProgress(listHTOrderListResp.getId());
            listHTOrderListResp.setProgress(i);
        });
        return hTorderListPage;
    }

    @Override
    public IPage<ListYPOrderListResp> getYPorderListPage(PageParam pageParam, Map<String, Object> queryParam) {
        //分页信息
        Page<ListYPOrderListResp> page = new Page<>();
        PageUtils.createPage(page, pageParam);
        QueryWrapper<ListYPOrderListResp> query = new QueryWrapper<>();
        query.allEq(queryParam);
        return orderMapper.getYPorderListPage(page, query);
    }

    /**
     * 发货管理列表
     *
     * @param pageParam
     * @param queryParam
     * @return
     */
    @Override
    public IPage<ListOrderItemInfoResp> getSendGoodsList(PageParam pageParam, Map<String, Object> queryParam) {
        //分页信息
        Page<ListOrderItemInfoResp> page = new Page<>();
        PageUtils.createPage(page, pageParam);
        QueryWrapper<ListOrderItemInfoResp> query = new QueryWrapper<>();
        query.allEq(queryParam);
        Page<ListOrderItemInfoResp> sendGoodsInfoList = orderItemMapper.getSendGoodsInfoList(page, query);
        for (ListOrderItemInfoResp record : sendGoodsInfoList.getRecords()) {
            //订单数量
            int size = record.getSize();
            //已发货数量
            int shippedSize = record.getShippedSize();
            //当前库存
            StorageCurrentInfo byItemId = storageCurrentInfoMapper.getByItemId(record.getItemId(), StorageType.CPK.getCode());
            if (byItemId != null) {
                //设置剩余数量/库存数量
                record.setSurplusAndTotal((size - shippedSize) + "/" + byItemId.getAllocatableSize());
            }else {
                record.setSurplusAndTotal((size - shippedSize) + "/" +0);
            }


            if (shippedSize <= 0)
                record.setStatus(OrderItemStatusEnum.DFH);
            else if (shippedSize < size)
                record.setStatus(OrderItemStatusEnum.FHZ);
            else
                record.setStatus(OrderItemStatusEnum.YWC);
        }
        return sendGoodsInfoList;
    }

    @Override
    public ShowOrderNumDto getOrderNum() {
        ShowOrderNumDto showOrderNumDto = new ShowOrderNumDto();
        showOrderNumDto.setOrderNum(0);
        showOrderNumDto.setCshOrderNum(0);
        showOrderNumDto.setDfpOrderNum(0);
        showOrderNumDto.setSczOrderNum(0);
        showOrderNumDto.setDrkOrderNum(0);
        showOrderNumDto.setWfOrderNum(0);
        showOrderNumDto.setYrkOrderNum(0);
        int sum = 0;
        List<OrderNumDto> orderNum = orderMapper.getOrderNum();

        for(int i=0; i<orderNum.size();i++){
            sum += orderNum.get(i).getNum();
            if(orderNum.get(i).getStatus()!=null) {
                switch (orderNum.get(i).getStatus()) {
                    case 0:
                        showOrderNumDto.setCshOrderNum(orderNum.get(i).getNum());
                        break;
                    case 1:
                        showOrderNumDto.setCshOrderNum(orderNum.get(i).getNum());
                        break;
                    case 2:
                        showOrderNumDto.setDfpOrderNum(orderNum.get(i).getNum());
                        break;
                    case 3:
                        showOrderNumDto.setSczOrderNum(orderNum.get(i).getNum());
                        break;
                    case 4:
                        showOrderNumDto.setDrkOrderNum(orderNum.get(i).getNum());
                        break;
                    case 5:
                        showOrderNumDto.setWfOrderNum(orderNum.get(i).getNum());
                        break;
                    case 6:
                        showOrderNumDto.setYrkOrderNum(orderNum.get(i).getNum());
                        break;
                }
            }
        }
        showOrderNumDto.setOrderNum(sum);
        return showOrderNumDto;
    }

    @Override
    public PersonRankingDto getPersonRanking() {
        PersonRankingDto personRankingDto = new PersonRankingDto();
//        SysUser current = CurrentUserContext.current();
        //TODO temp
        SysUser current = new SysUser(8L,"王巨壁","12345",new ArrayList<>());
        //查询得到销售金额和下单人Id
        List<PersonRankingDto> personRanking = orderMapper.getPersonRanking();
        for(int i=0; i<personRanking.size(); i++){
             if(current.getId()==personRanking.get(i).getUnderOrderId()){
                 personRankingDto = personRanking.get(i);
                //获取排名
                personRankingDto.setRanking(i+1);
            }
        }
        //如果当前登陆人员的排名不是第一，则获取前一名的销售金额
        if(personRankingDto.getRanking()!=0) {
            PersonRankingDto beforePersonRankingDto = personRanking.get(personRankingDto.getRanking() - 2);
            //获取差额
            personRankingDto.setBalance(beforePersonRankingDto.getOffer()-personRankingDto.getOffer());
        }else{
            personRankingDto.setBalance(0.0);
            personRankingDto.setRanking(1);
        }
        return personRankingDto;
    }

    @Override
    public Boolean updateSampleOrder(Long orderId) {
        Order order = new Order();
        order.setId(orderId);
        order.setSampleStatus(OrderSampleStatusEnum.WC);
        if (updateById(order)) {
            QueryWrapper<OrderItem> orderItemQueryWrapper = new QueryWrapper<>();
            orderItemQueryWrapper.eq("orderId", orderId);

            OrderItem one = iOrderItemService.getOne(orderItemQueryWrapper);
            one.setStatus(OrderItemStatusEnum.YWC);
            iOrderItemService.updateById(one);

            Long itemId = one.getItemId();
            return itemService.updateProductStatus(itemId, ItemStatusEnum.ZC.getDescp());

        }
        return false;
    }
}
